from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from api_key import handler as api_key_handler
from api_key import get_api_key
import hmac
import hashlib
import logging
import urllib
from google.appengine.api import users
import re

def error(handler, message):
    handler.response.headers['Content-Type'] = 'application/json; charset=utf-8'
    handler.response.set_status(500)
    logging.error(message)
    handler.response.out.write('{"class" : "%s"}' % message)
     
def verify_api_sig(request_url, secret_key, api_sig):
    sig = hmac.new(str(secret_key),
                   msg=request_url,
                   digestmod=hashlib.sha1).hexdigest()
    logging.info(str(sig))
    return api_sig == sig

def check_request(request):
    #0. Read necessary parameters
    api_key = request.get('api_key')
    api_sig = request.get('api_sig')
    api = get_api_key(api_key)
    if not api or not api_sig:
        return False
    #1. remove api_sig
    params = dict([x.split('=')
                   for x in request.query_string.split('&')])
    del params['api_sig']
    
    #2. sort all parameters (a --> z)
    tmp = params.items()
    tmp.sort()
    
    #3. rebuld URL request
    query_string = '&'.join([k+'='+urllib.quote(str(v))
                             for (k,v) in tmp])
    
    #4. verify signature
    return verify_api_sig(request.path + '?' + query_string, api.secret_key, api_sig)

class HttpServices(webapp.RequestHandler):
    def common(self, handler, method):
        self.response.headers['Content-Type'] = 'application/json; charset=utf-8'
        logging.info('is_admin: %s' % users.is_current_user_admin())
        if((not check_request(handler.request)) and (not users.is_current_user_admin())):
            #failed
            error(self, 'IncorrectSignatureException')
            self.response.set_status(500)
            self.response.out.write('{ "class" : "IncorrectSignatureException"}')
            return
        #success
        #1.service =?
        p = re.compile(r'/(\w+)/(\w+)')
        m = p.match(handler.request.path)
        if not m:
            error(self,'UnderfinedService')
            return
        
        service = m.group(1)
        method = m.group(2)
        #2. find the corresponding service
        # on the server
        module = None
        try:
            module = __import__(service)
        except:
            error(self,'UndefinedServiceExpception')
#            exc_type, exc_value, exc_traceback = sys.exc_info()
#            logging.info(repr(traceback.format_exception(exc_type, exc_value, exc_traceback)))
            return
        #3.dynamic call to service/method = ?
        try:
            getattr(module,method).__call__(handler)
        except:
            error(self,'InternalServiceExpception')
#            exc_type, exc_value, exc_traceback = sys.exc_info()
#            logging.info(repr(traceback.format_exception(exc_type, exc_value, exc_traceback)))
            return
        
        
        #verified
#        self.response.out.write('{ "hello" : "%s"}' % self.request.get('name'))
        
    def post(self):
        self.common(self, 'POST')
    def get(self):
        self.common(self, 'GET')

application = webapp.WSGIApplication([('/api_key/add',api_key_handler.AddApiKey),
                                      ('/api_key/list', api_key_handler.ListApiKey),
                                      ('/api_key/delete', api_key_handler.DeleteApiKey),
                                      ('/api_key/delete_l', api_key_handler.DeleteApiKey2),
                                      ('/api_key/edit', api_key_handler.EditApiKey),
                                      ('/api_key/update_edit', api_key_handler.UpdateEdit),
                                      (r'/.*', HttpServices)], debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
